package org.opengauss.mppdbide.bl.mock.debug;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;

import org.opengauss.mppdbide.bl.mock.debug.GaussMockPreparedStatementToHang;
import org.opengauss.mppdbide.bl.mock.debug.GaussMockPreparedStatementToSleep;
import com.mockrunner.mock.jdbc.MockConnection;
import com.mockrunner.mock.jdbc.MockPreparedStatement;

public class MockConnectionStubPS extends MockConnection
{
    boolean isHangQuery;
    
    public MockConnectionStubPS(boolean isHang)
    {
        super();
        isHangQuery = isHang;
    }

    @Override
    public PreparedStatement prepareStatement(String sql) throws SQLException
    {
        MockPreparedStatement statement = null;
        if (isHangQuery)
        {
            statement = new GaussMockPreparedStatementToHang(this, sql);
        }
        else
        {
            statement = new GaussMockPreparedStatementToSleep(this, sql);
        }
        getPreparedStatementResultSetHandler().addPreparedStatement(statement);
        return statement;
    }

    @Override
    public PreparedStatement prepareStatement(String sql, int resultSetType,
            int resultSetConcurrency) throws SQLException
    {
        MockPreparedStatement statement = null;
        if (isHangQuery)
        {
            statement = new GaussMockPreparedStatementToHang(this, sql,
                    resultSetType, resultSetConcurrency);
        }
        else
        {
            statement = new GaussMockPreparedStatementToSleep(this, sql,
                    resultSetType, resultSetConcurrency);
        }
        getPreparedStatementResultSetHandler().addPreparedStatement(statement);
        return statement;
    }

    @Override
    public PreparedStatement prepareStatement(String sql, int resultSetType,
            int resultSetConcurrency, int resultSetHoldability)
            throws SQLException
    {
        MockPreparedStatement statement = null;
        if (isHangQuery)
        {
            statement
                = new GaussMockPreparedStatementToHang(this, sql, 
                    resultSetType, resultSetConcurrency, resultSetHoldability);
        }
        else
        {
            statement
            = new GaussMockPreparedStatementToSleep(this, sql, 
                resultSetType, resultSetConcurrency, resultSetHoldability);
        }
        
        getPreparedStatementResultSetHandler().addPreparedStatement(statement);
        return statement;
    }

    @Override
    public PreparedStatement
            prepareStatement(String sql, int autoGeneratedKeys)
                    throws SQLException
    {
        verifyAutoGeneratedKeysParameter(autoGeneratedKeys);
        MockPreparedStatement statement = null;
        if (isHangQuery)
        {
            statement
                = new GaussMockPreparedStatementToHang(this, sql,
                        autoGeneratedKeys == Statement.RETURN_GENERATED_KEYS);
        }
        else
        {
            statement
            = new GaussMockPreparedStatementToSleep(this, sql,
                    autoGeneratedKeys == Statement.RETURN_GENERATED_KEYS);
        }
        getPreparedStatementResultSetHandler().addPreparedStatement(statement);
        return statement;    }

    @Override
    public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
            throws SQLException
    {
        return prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
    }

    @Override
    public PreparedStatement prepareStatement(String sql, String[] columnNames)
            throws SQLException
    {
        return prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
    }

    
    
    @Override
    public Statement createStatement() throws SQLException
    {
        MockStatementToHang statement = new MockStatementToHang(this);
        getStatementResultSetHandler().addStatement(statement);
        return statement;
    }

    @Override
    public Statement
            createStatement(int resultSetType, int resultSetConcurrency)
                    throws SQLException
    {
        MockStatementToHang statement = new MockStatementToHang(this, resultSetType, resultSetConcurrency);
        getStatementResultSetHandler().addStatement(statement);
        return statement;
    }

    @Override
    public Statement createStatement(int resultSetType,
            int resultSetConcurrency, int resultSetHoldability)
            throws SQLException
    {
        MockStatementToHang statement = new MockStatementToHang(this, resultSetType, resultSetConcurrency, resultSetHoldability);
        getStatementResultSetHandler().addStatement(statement);
        return statement;
    }

    private void verifyAutoGeneratedKeysParameter(int autoGeneratedKeys) throws SQLException
    {
        if(Statement.RETURN_GENERATED_KEYS != autoGeneratedKeys && Statement.NO_GENERATED_KEYS != autoGeneratedKeys)
        {
            throw new SQLException("autoGeneratedKeys must be either Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS");
        }
    }

    static boolean isHangClose = false;
    
    public static void setHangClose(boolean hangClose)
    {
        isHangClose = hangClose;
    }
    
    @Override
    public void close() throws SQLException
    {
        while (isHangClose)
        {
            try
            {
                Thread.sleep(100);
            }
            catch (InterruptedException e)
            {
                break;
            }
        }
        
        super.close();
    }
    
    
}
